use std::sync::mpsc::{channel, sync_channel};
use std::thread;

fn main() {
    // 单生产者单消费者的通信
    single();
    // 多生产者单消费者的通信
    mutil();
    // 使用同步通道通信
    sync_c();
}

// (异步通道) 单生产者单消费者的通信，也叫 流通道
fn single() {
    // tx是发送端，rx是接收端
    let (tx, rx) = channel();

    // 子线程 发送消息
    thread::spawn(move || {
        // send会返回一个Result, 使用unwrap是为了在线程间传播错误以便及时处理
        tx.send(10).unwrap();
    });

    // 主线程接收消息
    assert_eq!(rx.recv().unwrap(), 10);
}

// (异步通道) 多生产者单消费者的通信 , 也叫共享通道
fn mutil() {
    let (tx, rx) = channel();
    for i in 0..10 {
        let tx_c = tx.clone();
        thread::spawn(move || {
            tx_c.send(i).unwrap();
        });
    }

    for _ in 0..10 {
        let j = rx.recv().unwrap();
        assert!(0 <= j && j < 10);
    }
}

// 使用同步channel通信
fn sync_c() {
    // 同步有界通道，需要设置缓冲区大小
    let (tx, rx) = sync_channel(1);
    tx.send(1).unwrap();

    thread::spawn(move || {
        // tx move 到子线程里
        tx.send(2).unwrap();
    });

    assert_eq!(1, rx.recv().unwrap());
    assert_eq!(2, rx.recv().unwrap());
}
